package golf.stockdata.batch;

import golf.stockdata.framework.batch.Job;
import golf.stockdata.framework.hbmdao.Market;
import golf.stockdata.framework.hbmdao.Stock;
import golf.stockdata.framework.hbmdao.StockId;
import golf.stockdata.framework.util.hbm.HibernateUtil;
import golf.stockdata.framework.util.hbm.IdGenerator;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.htmlparser.beans.StringBean;

/**
 * A batch job to update the stock list.<br>
 * Parameters: <br>
 * - stockListURL : should be http://www.set.or.th/set/commonslookup.do?prefix=@PREFIX@&language=en&country=US
 * 
 * @author golf
 *
 */
public class UpdateStockListBatch implements Job{
	
	private static Logger logger = Logger.getLogger(UpdateStockListBatch.class);
	
	private String stockListURL;
	private String warrantListURL;
	private static String[] A_Z = {"NUMBER","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
	private Session session;
	private Timestamp createTs = new Timestamp(System.currentTimeMillis());
	private Map<String, String> stockNamesFromWEB = new HashMap<String, String>();
	private boolean isIntialized = false;

	public void initializeJob(HashMap<String, String> prop) {
		
		logger.debug(">>> initializeJob");
		
		stockListURL = prop.get("stockListURL");
		warrantListURL = prop.get("warrantListURL");
		
		session = HibernateUtil.createHibernatesession();
		
//		isIntialized = true;
		
		logger.debug("<<< initializeJob");
	}

	public void execute() {
		
		logger.debug(">>> execute");
		
		Transaction txn = session.beginTransaction();
		
        for(String prefix:A_Z){
        	
        	//Processing all common stocks
        	
        	String url = stockListURL.replaceAll("@PREFIX@", prefix);
        	
        	updateDB(url, 1);

        }
        
        if(warrantListURL != null){
        	
        	updateDB(warrantListURL, 2);
        	
        }
        
		Query queryStockData = session.getNamedQuery("latestStockDataByStockType")
				.setLong("stockType", (long)1);
		@SuppressWarnings("unchecked")
		List<Stock> stockList = queryStockData.list();
		
		for(Stock stock:stockList){
			
			if(stockNamesFromWEB.get(stock.getStockShortName().trim()) == null){
				
				logger.debug("Stock " + stock.getStockShortName() + " to be deleted");
				
				session.evict(stock);
				stock.setCrudValue("D");
				stock.getId().setStockHostTs(createTs);
				
				session.save(stock);
				
			}
		}
		
		queryStockData = session.getNamedQuery("latestStockDataByStockType")
				.setLong("stockType", (long)2);
		@SuppressWarnings("unchecked")
		List<Stock> warrantList = queryStockData.list();
		
		for(Stock warrant:warrantList){
			
			if(stockNamesFromWEB.get(warrant.getStockShortName().trim()) == null){
				
				logger.debug("Warrant " + warrant.getStockShortName() + " to be deleted");
				
				session.evict(warrant);
				warrant.setCrudValue("D");
				warrant.getId().setStockHostTs(createTs);
				
				session.save(warrant);
				
			}
		}
		
		

        logger.debug("Committing the session");
        txn.commit();
        logger.debug("Closing the session");
        session.close();
        
        logger.debug("<<< execute");
	}
	
	private void updateDB(String url, long stockType){
		
		StringBean sb = new StringBean ();
        sb.setLinks (false);
        sb.setReplaceNonBreakingSpaces (true);
        sb.setCollapse (true);
        sb.setURL (url);
        
        String[] outputLines = sb.getStrings().split("\\n");
        
        for(int i=0; i < outputLines.length; i++){

        	if(outputLines[i].indexOf("Total Search Result(s) :") >= 0){
        		int totalStock = Integer.parseInt(outputLines[i].split(":")[1]);
        		i = i + 4;
        		
        		for(int j=0; j < totalStock; j++){
        			
        			String stockShortName = outputLines[i++].trim().toUpperCase();
        			String companyName = outputLines[i++];
        			String market = outputLines[i++].trim().toUpperCase();
        			
        			stockNamesFromWEB.put(stockShortName,market);
        			
        			logger.debug("Processing stock:" + stockShortName);
        			logger.debug("Fullname:" + companyName);
        			logger.debug("Market name:" + market);

        			Query queryStockData = session.getNamedQuery("latestStockDataByName")
        					.setString("stockName", stockShortName);
        			Stock stock = (Stock)queryStockData.uniqueResult();
        			
        			if(stock == null){
        				
        				logger.debug("Found Market Data");
        				
            			Query queryMarketData = session.getNamedQuery("latestMarketDataByName")
            					.setString("marketName", market);
            			Market marketData = (Market) queryMarketData.uniqueResult();
            			
            			if(marketData != null){
            				
            				logger.debug("Not found in the DB, inserting ...");
            				
                			stock = new Stock(
            							new StockId(IdGenerator.getNext(), createTs), 
            							stockShortName, 
            							companyName, 
            							marketData.getId().getMarketId(), 
            							"C", stockType);
            				
            				session.save(stock);
            				
            			}else{
            				//TODO: Handling error here
            			}
        			}else{
        				
        				if(!stock.getStockFullName().trim().equals(companyName)){
        					
        					session.evict(stock);
        					stock.setCrudValue("U");
        					stock.setStockFullName(companyName);
        					stock.getId().setStockHostTs(createTs);
        					
            				session.save(stock);
            				
        				}
        			}
    				
        		}
        		
        		i = outputLines.length;
        	}
        	
        }
        
        
    }

	public boolean isIntialized() {
		return isIntialized;
	}

}
